package com.ruoyi.by.health.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.by.health.domain.entity.ByhealthEmpVoteLog;
import com.ruoyi.by.health.domain.entity.ByhealthEmployee;
import com.ruoyi.by.health.domain.entity.ByhealthPlaybill;
import com.ruoyi.by.health.domain.form.PlaybillVoteForm;
import com.ruoyi.by.health.domain.vo.PlayScoreResultVo;
import com.ruoyi.by.health.mapper.ByhealthEmpVoteLogMapper;
import com.ruoyi.by.health.mapper.ByhealthPlaybillMapper;
import com.ruoyi.by.health.service.IByhealthEmpVoteLogService;
import com.ruoyi.by.health.service.IByhealthEmployeeService;
import com.ruoyi.by.health.service.IByhealthPlaybillService;
import com.ruoyi.common.core.domain.AjaxResult;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 用户 业务层处理
 *
 * @author ruoyi
 */
@Service
public class ByhealthPlaybillServiceImpl implements IByhealthPlaybillService {
    private static final Logger log = LoggerFactory.getLogger(ByhealthPlaybillServiceImpl.class);
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    ByhealthPlaybillMapper playbillMapper;
    @Autowired
    IByhealthEmployeeService employeeService;
    @Autowired
    ByhealthEmpVoteLogMapper voteLogMapper;
    @Autowired
    IByhealthEmpVoteLogService  voteLogService;

    @Override
    public List<ByhealthPlaybill> selectPlaybillList(ByhealthPlaybill playbillQo) {
        List<ByhealthPlaybill> playbillList = playbillMapper.selectPlaybillList(playbillQo);
        Double temp = 0.00;
        for (int i = 0; i < playbillList.size(); i++) {
            ByhealthPlaybill playbill = playbillList.get(i);
            if (i!=playbillList.size()-1){
                PlayScoreResultVo playScoreResultVo=statsVoteVoByPlaybillId(playbill.getId());
                Double  playScore=playScoreResultVo.getPlayScore();
                playbill.setPlayScore(String.valueOf(playScore));
                playbill.setBossVote(playScoreResultVo.getBossCount());
                playbill.setEmpVote(playScoreResultVo.getEmpVote());
                temp=temp+playScore;
            }else {
                if("0.00".equals(String.valueOf(temp))){
                    playbill.setPlayScore("0.00");
                }else {
                    PlayScoreResultVo playScoreResultVo=statsVoteVoByPlaybillId(playbill.getId());
                    playbill.setBossVote(playScoreResultVo.getBossCount());
                    playbill.setEmpVote(playScoreResultVo.getEmpVote());
                    playbill.setPlayScore(String.valueOf(100.00-temp));
                }
            }
            playbillMapper.updateByPrimaryKeySelective(playbill);
        }
        return playbillList;

    }

    @Override
    public List<ByhealthPlaybill> selectPlaybillListByEmpId(Long empId) {
        ByhealthPlaybill playbillQo = new ByhealthPlaybill();
        List<ByhealthPlaybill> playbillList = playbillMapper.selectPlaybillList(playbillQo);
        List<ByhealthEmpVoteLog> voteLogList = voteLogMapper.getEmpVoteLogListByEmpId(empId);
        Double temp = 0.00;
        for (int i = 0; i < playbillList.size(); i++) {
            ByhealthPlaybill playbill = playbillList.get(i);
            for (ByhealthEmpVoteLog voteLog : voteLogList) {
                if (voteLog.getPlaybillId().equals(playbill.getId())) {
                    playbill.setIsVote(true);
                }
            }
            if (i!=playbillList.size()-1){
                Double  playScore=statsVoteByPlaybillId(playbill.getId());
                playbill.setPlayScore(String.valueOf(playScore));
                temp=temp+playScore;
            }else {
                if(0.00==temp){
                    playbill.setPlayScore("0.00");
                }else {
                    BigDecimal two = new BigDecimal(100.00-temp);
                    playbill.setPlayScore(String.valueOf(two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()));
                }
            }
        }
        return playbillList;
    }

    @Override
    public int savePlaybill(ByhealthPlaybill playbill) {
        return playbillMapper.insertSelective(playbill);
    }

    @Override
    public void savePlayScore() {
    }

    @Override
    public AjaxResult vote(PlaybillVoteForm playbillVoteForm) {
        Long empId = playbillVoteForm.getEmpId();
        //Long empId = 2L;
        ByhealthEmployee employee = employeeService.selectEmployeeByEmpId(empId);
        Object voteFormObject = redisTemplate.opsForHash().get("emp_bill_vote", empId);
        //log.info("-----投票结果voteFormObject：{}", JSON.toJSONString(voteFormObject));
        if (Objects.isNull(voteFormObject)) {
            playbillVoteForm.setEmpId(empId);
            playbillVoteForm.setBillIds(playbillVoteForm.getBillIds());
            playbillVoteForm.setIsStats(0);
            redisTemplate.opsForHash().put("emp_bill_vote", empId, playbillVoteForm);
            if (CollectionUtils.isNotEmpty(playbillVoteForm.getBillIds())) {
                for (Long billId : playbillVoteForm.getBillIds()) {
                    ByhealthEmpVoteLog byhealthEmpVoteLog = new ByhealthEmpVoteLog();
                    byhealthEmpVoteLog.setEmpId(empId);
                    byhealthEmpVoteLog.setPlaybillId(billId);
                    byhealthEmpVoteLog.setIsBoss(employee.getIsBoss());
                    voteLogService.insertEmpVoteLog(byhealthEmpVoteLog);
                }
            }
            return AjaxResult.success("投票成功");
        }
        PlaybillVoteForm playbillVoteFormResult = JSON.parseObject(JSON.parse(voteFormObject.toString()).toString(), PlaybillVoteForm.class);
        //log.info("-----投票实体转换结果playbillVoteQo：{}：", JSON.toJSONString(playbillVoteFormResult));
        List<Long> billIds = playbillVoteFormResult.getBillIds();
        if(employee.getIsBoss()==0){
            if (CollectionUtils.isNotEmpty(billIds) && billIds.size() >= 2) {
                //redisTemplate.opsForHash().delete("emp_bill_vote", empId);
                return AjaxResult.error("票数已用完");
            }
            playbillVoteForm.setEmpId(empId);
            playbillVoteForm.setBillIds(playbillVoteForm.getBillIds());
            playbillVoteForm.setIsStats(0);
            redisTemplate.opsForHash().put("emp_bill_vote", empId, playbillVoteForm);
            if (CollectionUtils.isNotEmpty(playbillVoteForm.getBillIds())) {
                for (Long billId : playbillVoteForm.getBillIds()) {
                    ByhealthEmpVoteLog byhealthEmpVoteLog = new ByhealthEmpVoteLog();
                    byhealthEmpVoteLog.setEmpId(empId);
                    byhealthEmpVoteLog.setPlaybillId(billId);
                    byhealthEmpVoteLog.setIsBoss(employee.getIsBoss());
                    voteLogService.insertEmpVoteLog(byhealthEmpVoteLog);
                    //statsVote();
                }
            }
            return AjaxResult.success("投票成功");
        }else {
            billIds.addAll(playbillVoteForm.getBillIds());
            playbillVoteForm.setEmpId(empId);
            playbillVoteForm.setBillIds(billIds);
            playbillVoteForm.setIsStats(0);
            redisTemplate.opsForHash().put("emp_bill_vote", empId, playbillVoteForm);
            if (CollectionUtils.isNotEmpty(playbillVoteForm.getBillIds())) {
                for (Long billId : playbillVoteForm.getBillIds()) {
                    ByhealthEmpVoteLog byhealthEmpVoteLog = new ByhealthEmpVoteLog();
                    byhealthEmpVoteLog.setEmpId(empId);
                    byhealthEmpVoteLog.setPlaybillId(billId);
                    byhealthEmpVoteLog.setIsBoss(employee.getIsBoss());
                    voteLogService.insertEmpVoteLog(byhealthEmpVoteLog);
                }
            }
            return AjaxResult.success("投票成功");
        }

    }

    @Override
    public AjaxResult statsVote() {
        Integer empCount = 0;
        Integer bossCount = 0;
        Map<Object, Object> resultMap = redisTemplate.opsForHash().entries("emp_bill_vote");
        //log.info("-----投票结果：{}", JSON.toJSONString(resultMap));
        List<Long> billIdList = new ArrayList<>();
        Map<Long, Integer> bossVotedMap = new HashMap<>();
        Map<Long, Integer> empVotedMap = new HashMap<>();
        for (Map.Entry<Object, Object> entry : resultMap.entrySet()) {
            //log.info("-----投票结果entry：" + entry.getKey() + " : " + entry.getValue());
            PlaybillVoteForm playbillVoteForm = JSON.parseObject(String.valueOf(entry.getValue()), PlaybillVoteForm.class);
            //log.info("-----投票实体转换结果playbillVoteQo：{}：", JSON.toJSONString(playbillVoteForm));
            Long empId = playbillVoteForm.getEmpId();
            List<Long> billIds = playbillVoteForm.getBillIds();
            billIdList.addAll(billIds);
            ByhealthEmployee employee = employeeService.selectEmployeeByEmpId(empId);
            //log.info("-----投票结果是否BOSS：" + employee.getIsBoss());
            if (1 == employee.getIsBoss()) {
                bossCount = bossCount + 1;
            } else {
                empCount = empCount + 1;
            }

            for (Long billId : billIds) {
                if (1 == employee.getIsBoss()) {
                    Integer bossVote = bossVotedMap.get(billId);
                    if (Objects.isNull(bossVote)) {
                        bossVote = 0;
                    }
                    bossVote = bossVote + 1;
                    bossVotedMap.put(billId, bossVote);
                    // 如果是老板 投票权重是 70%
                } else {
                    Integer empVote = empVotedMap.get(billId);
                    if (Objects.isNull(empVote)) {
                        empVote = 0;
                    }
                    empVote = empVote + 1;
                    empVotedMap.put(billId, empVote);
                }
            }
            playbillVoteForm.setIsStats(1);
            redisTemplate.opsForHash().put("emp_bill_vote", empId, playbillVoteForm);
        }
        //log.info("-----最终投票结果empVotedMap：{}", JSON.toJSONString(empVotedMap));
        //log.info("-----最终投票结果bossVotedMap：{}", JSON.toJSONString(bossVotedMap));
        List<ByhealthPlaybill> playbillList = playbillMapper.selectPlaybillListByIds(billIdList);
        if (!CollectionUtils.isEmpty(playbillList)) {
            for (ByhealthPlaybill playbill : playbillList) {
                Integer bossVote = bossVotedMap.get(playbill.getId());
                if (Objects.isNull(bossVote)) {
                    bossVote = 0;
                }
                Integer empVote = empVotedMap.get(playbill.getId());
                if (Objects.isNull(empVote)) {
                    empVote = 0;
                }
                playbill.setBossVote(bossVote);
                playbill.setEmpVote(empVote);
                playbill.setPlayScore(getPlayScoreString(bossCount, empCount, bossVote, empVote));
                playbillMapper.updateByPrimaryKeySelective(playbill);
            }
        }
        return AjaxResult.success(playbillList);
    }

    private Double statsVoteByPlaybillId(Long playbillId) {
        Integer empCount = 0;
        Integer bossCount = 0;
        Map<Object, Object> resultMap = redisTemplate.opsForHash().entries("emp_bill_vote");
        //log.info("-----投票结果：{}", JSON.toJSONString(resultMap));
        List<Long> billIdList = new ArrayList<>();
        Map<Long, Integer> bossVotedMap = new HashMap<>();
        Map<Long, Integer> empVotedMap = new HashMap<>();
        if(Objects.nonNull(resultMap) && resultMap.size() > 0) {
            for (Map.Entry<Object, Object> entry : resultMap.entrySet()) {
                //log.info("-----投票结果entry：" + entry.getKey() + " : " + entry.getValue());
                PlaybillVoteForm playbillVoteForm = JSON.parseObject(String.valueOf(entry.getValue()), PlaybillVoteForm.class);
                //log.info("-----投票实体转换结果playbillVoteQo：{}：", JSON.toJSONString(playbillVoteForm));
                Long empId = playbillVoteForm.getEmpId();
                List<Long> billIds = playbillVoteForm.getBillIds();
                billIdList.addAll(billIds);
                Object employeeObj = redisTemplate.opsForValue().get("emp_info-" + empId);
                ByhealthEmployee employee = JSON.parseObject(String.valueOf(employeeObj), ByhealthEmployee.class);
                //log.info("-----员工信息转换结果employee：{}：", JSON.toJSONString(employee));
                //log.info("-----投票结果是否BOSS：" + employee.getIsBoss());
                for (Long billId : billIds) {
                    if (1 == employee.getIsBoss()) {
                        bossCount = bossCount + 1;
                        Integer bossVote = bossVotedMap.get(billId);
                        if (Objects.isNull(bossVote)) {
                            bossVote = 0;
                        }
                        bossVote = bossVote + 1;
                        bossVotedMap.put(billId, bossVote);
                        // 如果是老板 投票权重是 70%
                    } else {
                        empCount = empCount + 1;
                        Integer empVote = empVotedMap.get(billId);
                        if (Objects.isNull(empVote)) {
                            empVote = 0;
                        }
                        empVote = empVote + 1;
                        empVotedMap.put(billId, empVote);
                    }
                }
                playbillVoteForm.setIsStats(1);
                redisTemplate.opsForHash().put("emp_bill_vote", empId, playbillVoteForm);
            }
            //log.info("-----最终投票结果empVotedMap：{}", JSON.toJSONString(empVotedMap));
            //log.info("-----最终投票结果bossVotedMap：{}", JSON.toJSONString(bossVotedMap));
            HashSet<Long> playbillIdSet = new HashSet<>(billIdList);
            if(CollectionUtils.isNotEmpty(playbillIdSet)) {
            //List<ByhealthPlaybill> playbillList = playbillMapper.selectPlaybillListByIdSet(playbillIdSet);
            Integer bossVote = bossVotedMap.get(playbillId);
            if (Objects.isNull(bossVote)) {
                bossVote = 0;
            }
            Integer empVote = empVotedMap.get(playbillId);
            if (Objects.isNull(empVote)) {
                empVote = 0;
            }
            return getPlayScore(bossCount, empCount, bossVote, empVote);}
            else {
                return 0.00;
            }
        } else {
            return 0.00;
        }
    }
    private PlayScoreResultVo statsVoteVoByPlaybillId(Long playbillId) {
        Integer empCount = 0;
        Integer bossCount = 0;
        Map<Object, Object> resultMap = redisTemplate.opsForHash().entries("emp_bill_vote");
        //log.info("-----投票结果：{}", JSON.toJSONString(resultMap));
        List<Long> billIdList = new ArrayList<>();
        Map<Long, Integer> bossVotedMap = new HashMap<>();
        Map<Long, Integer> empVotedMap = new HashMap<>();
        if(Objects.nonNull(resultMap) && resultMap.size() > 0) {
            for (Map.Entry<Object, Object> entry : resultMap.entrySet()) {
                //log.info("-----投票结果entry：" + entry.getKey() + " : " + entry.getValue());
                PlaybillVoteForm playbillVoteForm = JSON.parseObject(String.valueOf(entry.getValue()), PlaybillVoteForm.class);
                //log.info("-----投票实体转换结果playbillVoteQo：{}：", JSON.toJSONString(playbillVoteForm));
                Long empId = playbillVoteForm.getEmpId();
                List<Long> billIds = playbillVoteForm.getBillIds();
                billIdList.addAll(billIds);
                Object employeeObj = redisTemplate.opsForValue().get("emp_info-" + empId);
                ByhealthEmployee employee = JSON.parseObject(String.valueOf(employeeObj), ByhealthEmployee.class);
                //log.info("-----员工信息转换结果employee：{}：", JSON.toJSONString(employee));
                //log.info("-----投票结果是否BOSS：" + employee.getIsBoss());
                for (Long billId : billIds) {
                    if (1 == employee.getIsBoss()) {
                        bossCount = bossCount + 1;
                        Integer bossVote = bossVotedMap.get(billId);
                        if (Objects.isNull(bossVote)) {
                            bossVote = 0;
                        }
                        bossVote = bossVote + 1;
                        bossVotedMap.put(billId, bossVote);
                        // 如果是老板 投票权重是 70%
                    } else {
                        empCount = empCount + 1;
                        Integer empVote = empVotedMap.get(billId);
                        if (Objects.isNull(empVote)) {
                            empVote = 0;
                        }
                        empVote = empVote + 1;
                        empVotedMap.put(billId, empVote);
                    }
                }
                playbillVoteForm.setIsStats(1);
                redisTemplate.opsForHash().put("emp_bill_vote", empId, playbillVoteForm);
            }
            //log.info("-----最终投票结果empVotedMap：{}", JSON.toJSONString(empVotedMap));
            //log.info("-----最终投票结果bossVotedMap：{}", JSON.toJSONString(bossVotedMap));
            HashSet<Long> playbillIdSet = new HashSet<>(billIdList);
            PlayScoreResultVo  playScoreResultVo = new PlayScoreResultVo();
            if(CollectionUtils.isNotEmpty(playbillIdSet)) {
                //List<ByhealthPlaybill> playbillList = playbillMapper.selectPlaybillListByIdSet(playbillIdSet);
                Integer bossVote = bossVotedMap.get(playbillId);
                if (Objects.isNull(bossVote)) {
                    bossVote = 0;
                }
                Integer empVote = empVotedMap.get(playbillId);
                if (Objects.isNull(empVote)) {
                    empVote = 0;
                }
                playScoreResultVo.setPlayScore(getPlayScore(bossCount, empCount, bossVote, empVote));
                playScoreResultVo.setBossCount(bossCount);
                playScoreResultVo.setBossVote(empCount);
                playScoreResultVo.setEmpCount(bossVote);
                playScoreResultVo.setEmpVote(empVote);
                return playScoreResultVo;
            }
            else {
                playScoreResultVo.setPlayScore(0.00);
                playScoreResultVo.setBossCount(0);
                playScoreResultVo.setBossVote(0);
                playScoreResultVo.setEmpCount(0);
                playScoreResultVo.setEmpVote(0);

                return playScoreResultVo;
            }
        } else {
            PlayScoreResultVo  playScoreResultVo = new PlayScoreResultVo();
            playScoreResultVo.setPlayScore(0.00);
            playScoreResultVo.setBossCount(0);
            playScoreResultVo.setBossVote(0);
            playScoreResultVo.setEmpCount(0);
            playScoreResultVo.setEmpVote(0);

            return playScoreResultVo;
        }
    }

    private String getPlayScoreString(Integer bossCount, Integer empCount, Integer bossVote, Integer empVote) {
        //log.info("-----统计投票参数bossCount：{},empCount:{},bossVote:{},empVote:{}", bossCount, empCount, bossVote, empVote);
        Double playScore = 0.0;
        if (bossCount == 0&&empCount != 0) {
            playScore=(empVote / Double.valueOf(( empCount)) * 100);
            BigDecimal two = new BigDecimal(playScore);
            String playScoreString=  String.valueOf(two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
            log.info("-----统计投票结果playScoreString1:{}", playScoreString);
            return playScoreString;
        }
            if (empCount == 0&&bossCount != 0) {
                playScore=(bossVote / ( Double.valueOf(bossCount)) * 100);
                BigDecimal two = new BigDecimal(playScore);
                String playScoreString= String.valueOf(two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
                log.info("-----统计投票结果playScoreString2:{}", playScoreString);
                return playScoreString;
        }
        if (bossCount == 0 && empCount == 0) {
            return "0.0";
        }
        playScore = (((empVote / Double.valueOf(empCount)) * (0.3) + ((bossVote / Double.valueOf(bossCount)) * (0.7)))) * 100;
        BigDecimal two = new BigDecimal(playScore);
        String playScoreString= String.valueOf(two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        log.info("-----统计投票结果playScore3:{}", playScoreString);
        return playScoreString;
    }

    private Double getPlayScore(Integer bossCount, Integer empCount, Integer bossVote, Integer empVote) {
        //log.info("-----统计投票参数bossCount：{},empCount:{},bossVote:{},empVote:{}", bossCount, empCount, bossVote, empVote);
        Double playScore = 0.00;
        if (bossCount == 0&&empCount != 0) {
            playScore=(empVote / Double.valueOf(( empCount)) * 100);
            BigDecimal two = new BigDecimal(playScore);
            log.info("-----统计投票结果playScoreString1:{}", two.toString());
            return two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        if (empCount == 0&&bossCount != 0) {
            playScore=(bossVote / ( Double.valueOf(bossCount)) * 100);
            BigDecimal two = new BigDecimal(playScore);
            log.info("-----统计投票结果playScoreString2:{}", two.toString());
            return two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        if (bossCount == 0 && empCount == 0) {
            return 0.00;
        }
        playScore = (((empVote / Double.valueOf(empCount)) * (0.3) + ((bossVote / Double.valueOf(bossCount)) * (0.7)))) * 100;
        BigDecimal two = new BigDecimal(playScore);
        log.info("-----统计投票结果playScore3:{}", two.toString());
        return two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();

    }

}
